package main

import (
	"database/sql"
	"fmt"
	pb "ihos/ihos"
	"log"
)

type yiyuan struct {
	id       int32 //PK
	mc       string
	dz       string
	phone1   string
	phone2   string
	lat      float64
	lng      float64
	area     string
	area2    string
	area3    string
	password string
	bm       string
	isfy     int32
	zy       int32
	delay    int32
}

func (d *yiyuan) GetFromDB(id int32) error {
	sql := "SELECT id,mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay FROM yiyuan WHERE id=$1"
	return DBConn.db.QueryRow(sql, id).Scan(&d.id, &d.mc, &d.dz, &d.phone1, &d.phone2, &d.lat, &d.lng, &d.area, &d.area2, &d.area3, &d.password, &d.bm, &d.isfy, &d.zy, &d.delay)
}

func (d *yiyuan) GetFromDBByMC(mc string) error {
	sql := "SELECT id,mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay FROM yiyuan WHERE mc=$1"
	return DBConn.db.QueryRow(sql, mc).Scan(&d.id, &d.mc, &d.dz, &d.phone1, &d.phone2, &d.lat, &d.lng, &d.area, &d.area2, &d.area3, &d.password, &d.bm, &d.isfy, &d.zy, &d.delay)
}

func (d *yiyuan) GetFromDBByBM(bm string) error {
	sql := "SELECT id,mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay FROM yiyuan WHERE bm=$1"
	return DBConn.db.QueryRow(sql, bm).Scan(&d.id, &d.mc, &d.dz, &d.phone1, &d.phone2, &d.lat, &d.lng, &d.area, &d.area2, &d.area3, &d.password, &d.bm, &d.isfy, &d.zy, &d.delay)
}

func (d *yiyuan) GetYiYuanList() (yys []*yiyuan, err error) {
	// log.Println("GetGuaHaoList:", w)
	var rows *sql.Rows
	out := make([]*yiyuan, 0)
	sqlStr := ""
	if d.id > 0 {
		sqlStr = "SELECT id,mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay FROM yiyuan WHERE id=" + fmt.Sprint(d.id)
	} else {
		sqlStr = "SELECT id,mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay FROM yiyuan"
		cond := make([]string, 0)
		if len(d.area) > 0 {
			cond = append(cond, "area='"+d.area+"'")
		}
		if len(d.area2) > 0 {
			cond = append(cond, "area2='"+d.area2+"'")
		}
		if len(d.area3) > 0 {
			cond = append(cond, "area3='"+d.area3+"'")
		}
		if len(cond) > 0 {
			sqlStr += " WHERE "
			sep := ""
			for _, v := range cond {
				sqlStr += sep + v
				sep = " AND "
			}
		}
		sqlStr += " ORDER BY id LIMIT 500"
	}
	log.Println("SQL:", sqlStr)
	rows, err = DBConn.db.Query(sqlStr)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		w := &yiyuan{}
		if err = rows.Scan(&w.id, &w.mc, &w.dz, &w.phone1, &w.phone2, &w.lat, &w.lng, &w.area, &w.area2, &w.area3, &w.password, &w.bm, &w.isfy, &w.zy, &w.delay); err != nil {
			log.Println(err)
			//return nil, err
		} else {
			out = append(out, w)
		}
	}
	return out, nil
}

func (d *yiyuan) GetYiYuanListWithinDistance(lat, lng, distance float64) (yys []*yiyuan, err error) {
	// log.Println("GetGuaHaoList:", w)
	var rows *sql.Rows
	out := make([]*yiyuan, 0)
	sqlStr := "SELECT id,mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay FROM yiyuan where earth_distance(ll_to_earth(lat,lng), ll_to_earth(" + fmt.Sprint(lat) + "," + fmt.Sprint(lng) + ")) < " + fmt.Sprint(distance)
	sqlStr += " ORDER BY id LIMIT 500"
	log.Println("SQL:", sqlStr)
	rows, err = DBConn.db.Query(sqlStr)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		w := &yiyuan{}
		if err = rows.Scan(&w.id, &w.mc, &w.dz, &w.phone1, &w.phone2, &w.lat, &w.lng, &w.area, &w.area2, &w.area3, &w.password, &w.bm, &w.isfy, &w.zy, &w.delay); err != nil {
			log.Println(err)
			//return nil, err
		} else {
			out = append(out, w)
		}
	}
	return out, nil
}

func (d *yiyuan) SaveToDB(id int32) error {
	sql := ""
	var err error
	if id > 0 { //update
		sql = "UPDATE yiyuan set mc=$1,dz=$2,phone1=$3,phone2=$4,lat=$5,lng=$6,area=$7,area2=$8,area3=$9,password=$10,bm=$11,isfy=$12,zy=$13,delay=$14 where id=$15 RETURNING id"
		err = DBConn.db.QueryRow(sql, d.mc, d.dz, d.phone1, d.phone2, d.lat, d.lng, d.area, d.area2, d.area3, d.password, d.bm, d.isfy, d.zy, d.delay, d.id).Scan(&d.id)
	} else { //insert
		sql = "INSERT INTO yiyuan(mc,dz,phone1,phone2,lat,lng,area,area2,area3,password,bm,isfy,zy,delay)VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14) RETURNING id"
		err = DBConn.db.QueryRow(sql, d.mc, d.dz, d.phone1, d.phone2, d.lat, d.lng, d.area, d.area2, d.area3, d.password, d.bm, d.isfy, d.zy, d.delay).Scan(&d.id)
	}
	return err
}

func (w *yiyuan) toPB() *pb.YiYuan {
	y := &pb.YiYuan{
		ID:     w.id,
		BM:     w.bm,
		MC:     w.mc,
		DZ:     w.dz,
		ZYID:   w.zy,
		Phone1: w.phone1,
		Phone2: w.phone2,
		Lat:    w.lat,
		Lng:    w.lng,
		Area:   w.area,
		Area2:  w.area2,
		Area3:  w.area3,
		Delay:  w.delay,
	}
	if w.isfy == 1 {
		y.ISFY = true
	} else {
		y.ISFY = false
	}
	return y
}

func (w *yiyuan) fromPB(p *pb.YiYuan) *yiyuan {
	w.id = p.GetID()
	w.mc = p.GetMC()
	w.dz = p.GetDZ()
	w.phone1 = p.GetPhone1()
	w.phone2 = p.GetPhone2()
	w.lat = p.GetLat()
	w.lng = p.GetLng()
	w.area = p.GetArea()
	w.area2 = p.GetArea2()
	w.area3 = p.GetArea3()
	w.bm = p.GetBM()
	w.delay = p.GetDelay()
	if p.GetISFY() == true {
		w.isfy = 1
	} else {
		w.isfy = 0
	}
	w.zy = p.GetZYID()
	return w
}
